﻿using System.Collections;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using UnityEngine.SceneManagement;
using System;
using Swift;

public class Game : MonoBehaviour {

	public AudioSource source;
	public GameObject Config;
	public string GameName;
		
	void Awake() {
		Config = GameObject.Find ("Config");
		GameName = Config.GetComponent<GameDriver> ().GameName;

		GameCore gc = GameCore.Instance;

		PlayerController pc = new PlayerController ();
		pc.GameName = GameName;
		pc.Conn = gc.SrvConn;
		gc.Add ("PC", pc);

		Factory factory = new Factory ();
		factory.Game = this;
		gc.Add ("Factory", factory);

		IWriteableBuffer buff = gc.SrvConn.BeginSend (pc.GameName);
		buff.Write ("Ready");
		gc.SrvConn.End (buff);
	}

	void Update() {
		if (source.isPlaying == false) {
			source.clip = Resources.Load<AudioClip> ("music/back2.mp3");
			source.loop = true;
			source.Play ();
		} 
	}

	public GameObject Create(int tid, float _x, float _y, int dir) {
		GameObject res = null;
		string addr = "prefabs/" + tid;

		if (addr != null) {
			res = Instantiate ( Resources.Load<GameObject>(addr) );
			Repos (res, _x, _y, dir);
		}
		return res;
	}

	#region 客户端特效

	HashSet<GameObject> flickerHash = new HashSet<GameObject> ();
	IEnumerator FlickerEffect(GameObject obj) {

		float t = 0.4f;
		while (obj != null && flickerHash.Contains(obj)) {

			obj.SetActive ( !obj.activeSelf ); 

			yield return new WaitForSeconds (t);
			t -= t / 40;

		}

		if (flickerHash.Contains (obj)) {
			flickerHash.Remove (obj);
		}

		if (obj != null) {
			obj.SetActive (true);
		}

		yield return null;
	}

	public void Flicker(GameObject obj) {    // 闪烁效果
		if(flickerHash.Contains(obj)) return ;
		flickerHash.Add (obj);
		StartCoroutine (FlickerEffect (obj));
	}  

	public void StopFlicker(GameObject obj) {
		if (flickerHash.Contains (obj)) {
			flickerHash.Remove (obj);
		}
	}


	HashSet<GameObject> flashRed = new HashSet<GameObject>();

	IEnumerator FlashRedEffect(GameObject obj) {
		
		Debug.Log ("闪红光");
		float t = 0f;
		float u = 0f;

		SpriteRenderer r = null;
		if (obj != null) {
			r = obj.GetComponent<SpriteRenderer> ();
		}
		while (obj != null && flashRed.Contains (obj)) {
			r.color = new Color (1f, t, t, 1f);

			if (t > 0.95) {
				u = -0.033f;
			} else if (t < 0.05) {
				u = 0.033f;
			}

			t += u;

			yield return null;
		}
		if (r != null) {
			r.color = Color.white;
		}
		yield return null;
	}

	public void FlashRed(GameObject obj) {
		if (flashRed.Contains (obj))
			return;
		flashRed.Add (obj);
		StartCoroutine (FlashRedEffect (obj));	
	}

	public void StopFlashRed(GameObject obj) {
		if (flashRed.Contains (obj)) {
			flashRed.Remove (obj);
		}
	}
		
	IEnumerator BulletEffect(Vector3 position) {
		GameObject obj;

		for (int i = 1; i <= 3; i++) {
			obj = Instantiate ( Resources.Load<GameObject>("prefabs/b" + i) );
			obj.transform.position = position;
			yield return new WaitForSeconds (0.03f);
			Destroy (obj);
		}
			
		yield return null;
	}

	public void BulletEffect(GameObject obj) {
		StartCoroutine (BulletEffect (obj.transform.position));
	}

	IEnumerator TankEffect(Vector3 position) {
		GameObject obj;

		yield return new WaitForSeconds (0.07f);
		GameObject o = Instantiate(Resources.Load<GameObject>("prefabs/blastEffect"));
		o.transform.position = position;
		AudioSource s = o.GetComponent<AudioSource> ();

		for (int i = 1; i <= 2; i++) {
			obj = Instantiate ( Resources.Load<GameObject>("prefabs/blast" + i) );
			obj.transform.position = position;
			yield return new WaitForSeconds (0.03f);
			Destroy (obj);
		}

		while (s.isPlaying) {
			yield return null;
		} 
			
		Destroy (o);

		yield return null;
	}

	public void TankEffect(GameObject obj) {
		StartCoroutine (TankEffect (obj.transform.position));
	}

	Dictionary<GameObject, int> invincibleDict = new Dictionary<GameObject, int> ();
	HashSet<GameObject> invincibleHash = new HashSet<GameObject> ();

	IEnumerator InvincibleEffect(GameObject obj, GameObject fa) {
		invincibleHash.Add (fa);
		obj = Instantiate (obj);
		obj.transform.position = fa.transform.position;
		yield return new WaitForSeconds (0.05f);
		Destroy (obj);
		invincibleHash.Remove (fa);
		yield return null;
	} 

	public void InvincibleEffect(GameObject obj) {
		if (!invincibleDict.ContainsKey (obj)) {
			invincibleDict [obj] = 1;
		}
		if (!invincibleHash.Contains (obj)) {
			int index = invincibleDict [obj];
			StartCoroutine (InvincibleEffect (Resources.Load<GameObject> ("prefabs/w" + index), obj));
			invincibleDict [obj] = index ^ 3; 
		} 
	}

	public void StopInvincibleEffect(GameObject obj) {
		if (invincibleDict.ContainsKey (obj)) {
			invincibleDict.Remove (obj);
		}
	}
		
	public void ShotEffect(GameObject obj) {
		AudioSource source = obj.GetComponent<AudioSource> ();
		source.Play ();
	}

	#endregion

	public void Remove(GameObject obj) {
		Destroy (obj);
	}

	public void Repos(GameObject obj, float x, float y, int dir) {
		float xc=0, yc=0;
		if (dir == 0) {
			xc += 1;
		} else if (dir == 1) {
			xc -= 1;
		} else if (dir == 2) {
			yc -= 1;
		} else {
			yc += 1;
		}

		Vector3 d = new Vector3 (yc, xc, 0);

		obj.transform.up = d;

		obj.transform.position = new Vector3 (y, x, 0);
	}

	public void Balance(int chapter, bool pass, int[,] num) {

		GameDriver driver = Config.GetComponent<GameDriver> ();
		driver.Chapter = chapter;
		driver.Pass = pass;
		driver.Num = num;

		SceneManager.LoadScene ("Settlement");
	}

	public int chapter;
	public int life1;
	public int life2;
	public int num;

	void OnGUI() {

		GUI.skin.label.fontSize = 20;

		if (Time.timeScale == 0) {
			GUI.color = Color.red;
			GUI.Label ( new Rect(Screen.width/2-35, Screen.height/2-20, 150, 40), "游戏暂停···" );
			GUI.color = Color.white;
		}


		int enemyNum = num;

		StringBuilder sb = new StringBuilder ();
		for (int i = 0; i < enemyNum; i++) {
			if (i % 2 == 0)
				sb.Append ("\n");
			sb.Append ("X");
		}

		GUI.Label (new Rect (Screen.width - 100, 20, 200, 300), sb.ToString());

		GUI.Label (new Rect (Screen.width - 100, 350, 200, 50), "P1:\n" + life1);
		GUI.Label (new Rect (Screen.width - 100, 425, 200, 50), "P2:\n" + life2);
		GUI.Label (new Rect (Screen.width - 100, 500, 200, 50), "第 " + chapter + " 关");

	}
}
